﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace IntoTheVoid.Units.Download
{
	public class DownloadHttpHelper
	{
		private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
		{
			return true;
		}
		private static readonly string[] UserAgents = new[]
		{
			"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
			"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
			"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
		};

		public static System.Net.HttpWebRequest GetHttpWebRequest(string url)
		{
			//HttpWebRequest request = null;
			//if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
			//{
			//	ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
			//	ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
			//	request = (HttpWebRequest)WebRequest.Create(url);
			//	request.ProtocolVersion = HttpVersion.Version10;
			//}
			//else
			//{
			//	request = WebRequest.Create(url) as HttpWebRequest;
			//}
			//return request;

			var request = (HttpWebRequest)WebRequest.Create(url);
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

			// 随机浏览器特征
			var rand = new Random();
			request.UserAgent = UserAgents[rand.Next(UserAgents.Length)];
			request.Headers["Accept-Language"] = "zh-CN,zh;q=0.9,en;q=0.8";
			request.Headers["Accept-Encoding"] = "gzip, deflate, br";
			request.AutomaticDecompression = DecompressionMethods.None;

			// 优化连接策略
			request.ServicePoint.ConnectionLeaseTimeout = 60 * 1000; // 60秒连接释放
			request.ServicePoint.MaxIdleTime = 50 * 1000;
			request.KeepAlive = true;

			return request;
		}

		public static long GetHttpLength(string url)
		{
			long length = -1L;
			try
			{
				var sourceFileUrl = System.Web.HttpUtility.UrlPathEncode(url);
				var webRequest = (HttpWebRequest)WebRequest.Create(sourceFileUrl);
				webRequest.Method = "HEAD";
				webRequest.Timeout = 10000;
				webRequest.Credentials = CredentialCache.DefaultCredentials;
				webRequest.Proxy = WebRequest.DefaultWebProxy;
				using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
				{
					if (response.StatusCode == HttpStatusCode.OK)
					{
						length = response.ContentLength;
					}
					if (length <= 0)
						throw new Exception();
				}
				return length;
			}
			catch (Exception ex)
			{
				LogHelper.Error(ex, "DownloadFile GetHttpLength  response.ContentLength:" + length);
				return length;
			}
		}
		public static void InitRequest(ref System.Net.HttpWebRequest request)
		{
			request.Accept = "text/json,*/*;q=0.5";
			request.Headers.Add("Accept-Charset", "utf-8;q=0.7,*;q=0.7");
			request.Headers.Add("Accept-Encoding", "gzip, deflate, x-gzip, identity; q=0.9");
			request.AutomaticDecompression = System.Net.DecompressionMethods.GZip;
			request.Timeout = 60000;
		}
		public static WebResponse Download(string downloadUrl, long from, long to, string method)
		{
			var request = DownloadHttpHelper.GetHttpWebRequest(downloadUrl);
			DownloadHttpHelper.InitRequest(ref request);
			request.AddRange(from, to);
			request.Method = method;
			request.Proxy = null;
			request.KeepAlive = true;
			request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
			request.Timeout = 1200000;
			request.ReadWriteTimeout = 1200000;
			request.ServicePoint.ConnectionLimit = 10;
			request.ContentType = "application/json; charset=utf-8";
			WebResponse result = null;
			try
			{
				result = request.GetResponse();
			}
			catch (Exception ex)
			{
				LogHelper.Error(ex, "WebResponse Download Error");
				throw ex;
			}
			return result;
		}
		public static string Get(string url, IDictionary<string, string> param)
		{
			var paramBuilder = new List<string>();
			foreach (var item in param)
			{
				paramBuilder.Add(string.Format("{0}={1}", item.Key, item.Value));
			}
			url = string.Format("{0}?{1}", url.TrimEnd('?'), string.Join(",", paramBuilder.ToArray()));
			return Get(url);
		}
		public static string Get(string url)
		{
			try
			{
				var request = GetHttpWebRequest(url);
				if (request != null)
				{
					string retval = null;
					InitRequest(ref request);
					using (var Response = request.GetResponse())
					{
						using (var reader = new System.IO.StreamReader(Response.GetResponseStream(), System.Text.Encoding.UTF8))
						{
							retval = reader.ReadToEnd();
						}
					}
					return retval;
				}
			}
			catch (Exception ex)
			{
				LogHelper.Error(ex, "DownloadFile Error url:" + url);
			}
			return null;
		}
	}

}
